package io.summer.basis.core;

import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.util.FastByteArrayOutputStream;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @author Moonlight
 */
@Slf4j
public class MyServletRequestWrapper extends HttpServletRequestWrapper {
  private final FastByteArrayOutputStream outputStream = new FastByteArrayOutputStream();
  /**
   * Creates a ServletRequest adaptor wrapping the given request object.
   *
   * @param request The request to wrap
   * @throws IllegalArgumentException if the request is null
   */
  public MyServletRequestWrapper(HttpServletRequest request) {
    super(request);
    try {
      IOUtils.copy(request.getInputStream(), outputStream);
    } catch (IOException e) {
      log.error("MyServletRequestWrapper error: ", e);
    }
  }

  /**
   * 注意，这里会产生一份复制
   * @return body in bytes.
   */
  public byte[] getBody() {
    return outputStream.toByteArray();
  }

  public String getBodyString() {
    return outputStream.toString();
  }

  @Override
  public BufferedReader getReader() throws IOException {
    return new BufferedReader(new InputStreamReader(new ByteArrayInputStream(outputStream.toByteArray())));
  }

  @Override
  public ServletInputStream getInputStream() throws IOException {
    final ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
    return new ServletInputStream() {
      @Override
      public int readLine(byte[] b, int off, int len) throws IOException {
        return inputStream.read(b, off, len);
      }

      @Override
      public boolean isFinished() {
        return inputStream.available() > 0;
      }

      @Override
      public boolean isReady() {
        return true;
      }

      @Override
      public void setReadListener(ReadListener arg0) {
        // TODO Auto-generated method stub
      }

      @Override
      public int read() throws IOException {
        return inputStream.read();
      }
    };
  }
}
